package com.moonshineproject.plugin.project
{
	import __AS3__.vec.Vector;
	
	import com.moonshineproject.IDEModel;
	import com.moonshineproject.events.CloseTabEvent;
	import com.moonshineproject.events.OpenFileEvent;
	import com.moonshineproject.plugin.IMenuPlugin;
	import com.moonshineproject.plugin.IPlugin;
	import com.moonshineproject.plugin.PluginBase;
	import com.moonshineproject.plugin.events.FilePluginEvent;
	import com.moonshineproject.plugin.menu.vo.MenuItem;
	import com.moonshineproject.plugin.project.view.TreeView;
	import com.moonshineproject.plugin.project.vo.ProjectVO;
	import com.moonshineproject.plugin.project.vo.flash.AS3ProjectVO;
	import com.moonshineproject.plugin.settings.ISettingsProvider;
	import com.moonshineproject.plugin.settings.SettingsView;
	import com.moonshineproject.plugin.settings.vo.ISetting;
	import com.moonshineproject.plugin.settings.vo.PathSetting;
	import com.moonshineproject.plugin.settings.vo.SettingsWrapper;
	import com.moonshineproject.plugin.settings.vo.StaticLabelSetting;
	import com.moonshineproject.plugin.settings.vo.StringSetting;
	import com.moonshineproject.utils.Utils;
	
	import flash.events.Event;
	import flash.filesystem.File;
	
	import mx.collections.ArrayCollection;
	
	import no.doomsday.console.ConsoleUtil;
	
	public class ProjectPlugin extends PluginBase implements IPlugin, ISettingsProvider, IMenuPlugin
	{
		public static const EVENT_PROJECT_SETTINGS:String = "projectSettingsEvent";
		public static const EVENT_NEW_AS3_PROJECT:String = "newAS3ProjectEvent";
		
		override public function get name():String 	{return "Project Plugin";}
		override public function get author():String 		{return "Moonshine Project Team";}
		override public function get description():String 	{return "Provides project settings.";}
		
		private var projects:ArrayCollection = new ArrayCollection();	
		private var treeView:TreeView;
		
		public function ProjectPlugin()
		{
			treeView = new TreeView();
			treeView.projects = this.projects;	
		}
		
		override public function activate():void
		{
			ConsoleUtil.addSystemMessage("Plugin Activation : ProjectPlugin"); 
			
			dispatcher.addEventListener(FilePluginEvent.EVENT_FILE_OPEN, handleFileOpen);
			dispatcher.addEventListener(EVENT_PROJECT_SETTINGS, handleShowSettings);
			dispatcher.addEventListener(EVENT_NEW_AS3_PROJECT, createAS3Project);
			
			_activated = true;
		
		}
		override public function deactivate():void
		{
			ConsoleUtil.addSystemMessage("Plugin DeActivation : ProjectPlugin"); 

			dispatcher.removeEventListener(FilePluginEvent.EVENT_FILE_OPEN, handleFileOpen);
			
			_activated = false;
		}
		
		public function getSettingsList():Vector.<ISetting>	
		{
			return new Vector.<ISetting>();
		}
		
		public function getMenu():MenuItem
		{
			// Since plugin will be activated if needed we can return null to block menu
			if( !_activated ) return null; 
			return new MenuItem("Project", [
				new MenuItem("Show Settings", null, EVENT_PROJECT_SETTINGS)
			]);
		}
		
		// If user opens project file, open project automagically
		private function handleFileOpen(event:FilePluginEvent):void
		{
			var isInProject:Boolean;
			for each (var p:ProjectVO in projects)
			{
				if ( p.isFileIncludedInProject(event.file) )
				{
					isInProject = true;
					break;
				}
			}
			
			if (event.file.extension == 'as3proj' // FlashDevelop project file ending
				|| event.file.name == '.project' // Eclipse & FB project files
				|| event.file.name == '.actionScriptProperties'
				|| event.file.name == '.flexProperties') 
			{
				// Assume user wants to open project					
				if (!isInProject)
				{
					event.preventDefault();
					var rootPath:String = Utils.getDirectoryPathFor(event.file);
					var root:File = new File(rootPath);
					openProject(root, event.file);
					event.preventDefault();
					showProjectPanel();
				}
			}
			else
			{
				// TODO: Look upwards 3-4 directories for project.
				// TODO: Ask user (in an unobtrusive manner) if opening the project is OK.
			}
		}
		
		private function showProjectPanel():void
		{
			if (!treeView.stage)
				IDEModel.getInstance().mainView.addPanel(treeView);
		}
		
		private function openProject(root:File, projectFile:File):void
		{
			var p:ProjectVO;
			if (projectFile.extension == "as3proj") {
				p = new AS3ProjectVO(root, projectFile);
			} else {
				p = new ProjectVO(root);
			}
			
			IDEModel.getInstance().activeProject = p;
			
			projects.addItem(p);
		}

		private function handleShowSettings(event:Event):void
		{
			var project:ProjectVO = IDEModel.getInstance().activeProject;
			if (project)
			{
				showSettings(IDEModel.getInstance().activeProject);
			} 
		}
		
		private function showSettings(project:ProjectVO):void
		{
			if (project is AS3ProjectVO)
			{
				var settingsView:SettingsView = new SettingsView();
				settingsView.addEventListener(SettingsView.EVENT_SAVE, settingsSave);
				
				var settingsLabel:String = project.name + " settings"; 
				settingsView.addCategory(settingsLabel);
				 				
				var categories:Vector.<SettingsWrapper> = AS3ProjectVO(project).getSettings();
				for each (var category:SettingsWrapper in categories)
				{
					settingsView.addSetting(category, settingsLabel);			
				}
				settingsView.label = settingsLabel;
				settingsView.associatedData = project;
				
				IDEModel.getInstance().editors.addItem( settingsView ); 
			}	
		}
		
		// If a SettingsView closes, look to see if it's settings for a project
		private function settingsSave(event:Event):void
		{
			var view:SettingsView = event.target as SettingsView;
			
			if (view && view.associatedData is ProjectVO)
			{
				var pvo:ProjectVO = view.associatedData as ProjectVO;
				pvo.saveSettings();
				
				if (projects.getItemIndex(pvo) == -1)
				{
					// Newly created project, add it to project explorer & show it
					projects.addItem(pvo);
					IDEModel.getInstance().activeProject = pvo;
					showProjectPanel();
					
					dispatcher.dispatchEvent( new CloseTabEvent(view) );
					
					if (pvo is AS3ProjectVO)
					{
						dispatcher.dispatchEvent( 
							new OpenFileEvent(OpenFileEvent.OPEN_FILE, AS3ProjectVO(pvo).targets[0])
						);
					}
				}
			} 
		}
		
		// Create new AS3 Project
		private function createAS3Project(event:Event):void
		{
			var settingsView:SettingsView = new SettingsView();
			settingsView.addEventListener(SettingsView.EVENT_SAVE, settingsSave);
			var project:AS3ProjectVO = new AS3ProjectVO(null, null);
			project.projectName = "NewProject";
				 
			settingsView.addCategory("");
				 				
			var settings:SettingsWrapper = new SettingsWrapper("Name & Location", Vector.<ISetting>([
				new StaticLabelSetting("New Actionscript 3 Project"),
				new StringSetting(project, 'projectName', 'Project Name'),
				new PathSetting(project, 'filePath', 'Project Directory', true)
			]));
			
			settingsView.addSetting(settings, "");
			
			settingsView.label = "New Project";
			settingsView.associatedData = project;
				
			IDEModel.getInstance().editors.addItem( settingsView );
		}
		
	}
}